home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / network / daemons / nfs / nfs-serv.2be / nfs-serv / nfs-server-2.2beta16 / rmtab.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-25  |  6.5 KB  |  326 lines

  1. /*
  2.  * A set of support routines for /etc/rmtab file managment. These routines
  3.  * are called from mountd.c.
  4.  *
  5.  * Written and Copyright by Dariush Shirazi, <dshirazi@uhl.uiowa.edu>
  6.  *
  7.  */
  8.  
  9. #include "nfsd.h"
  10. #include "rmtab.h"
  11.  
  12. static _PRO(char * rmtab_gethost, (struct svc_req *));
  13. static _PRO(int    rmtab_insert, (char *, char *));
  14. static _PRO(void   rmtab_file, (char));
  15.  
  16. /*
  17.  * global top to linklist
  18.  */
  19.  
  20. static mountlist rmtablist = NULL;
  21.  
  22. /*
  23.  * rmtab_add_client -- if client+path not in the list, add them.
  24.  */
  25.  
  26. void rmtab_add_client(path, rqstp)
  27. dirpath path;
  28. struct svc_req *rqstp;
  29. {
  30.     char        *hostname;
  31.  
  32.     hostname = rmtab_gethost(rqstp);
  33.     if (hostname != NULL) {
  34.         rmtab_file('r');
  35.         if (rmtab_insert(hostname, path))
  36.             rmtab_file('w');
  37.     }
  38. }
  39.  
  40. /*
  41.  * rmtab_lst_client -- return the top pointer.
  42.  */
  43.  
  44. mountlist *rmtab_lst_client()
  45. {
  46.     rmtab_file('r');
  47.     return(&rmtablist);
  48. }
  49.  
  50. /*
  51.  * rmtab_del_client -- delete a client+path
  52.  */
  53.  
  54. void rmtab_del_client(path, rqstp)
  55. dirpath path;
  56. struct svc_req *rqstp;
  57. {
  58.     int        p0, p1, changed;
  59.     char        *hostname;
  60.     mountlist    cur, prv;
  61.  
  62.     hostname = rmtab_gethost(rqstp);
  63.     dprintf(D_RMTAB, "\trmtab_del path='%s' host='%s'\n", path, hostname);
  64.     if (hostname == NULL)
  65.         return;
  66.  
  67.     rmtab_file('r');
  68.     changed = 0;
  69.  
  70.     for (cur = rmtablist, prv = NULL; cur; cur = cur->ml_next) {
  71.         p0 = strcmp(cur->ml_hostname, hostname);
  72.         p1 = strcmp(cur->ml_directory, path);
  73.         if (p0 == 0 && p1 == 0)
  74.             break;                /* already exists */
  75.         prv = cur;
  76.     }
  77.  
  78.     if (cur) {
  79.         /*
  80.          * don't free both ml_hostname & ml_directory.
  81.          * See rmtab_insert for details.
  82.          */
  83.         free(cur->ml_hostname);
  84.         if (prv)
  85.             prv->ml_next = cur->ml_next;
  86.         else
  87.             rmtablist    = cur->ml_next;
  88.         free(cur);
  89.  
  90.         changed = 1;
  91.     }
  92.  
  93.     if (changed)
  94.         rmtab_file('w');
  95. }
  96.  
  97. /*
  98.  * rmtab_mdel_client -- delete all the entry points for a client
  99.  */
  100.  
  101. void rmtab_mdel_client(rqstp)
  102. struct svc_req *rqstp;
  103. {
  104.     int        p0, changed;
  105.     char        *hostname;
  106.     mountlist    cur, prv, tmp;
  107.  
  108.     hostname = rmtab_gethost(rqstp);
  109.     dprintf(D_RMTAB, "\trmtab_mdel host='%s'\n", hostname);
  110.     if (hostname == NULL)
  111.         return;
  112.  
  113.     rmtab_file('r');
  114.     changed = 0;
  115.  
  116.     prv     = NULL;
  117.     cur     = rmtablist;
  118.     while (cur) {
  119.         p0 = strcmp(cur->ml_hostname, hostname);
  120.         if (p0 == 0) {
  121.             /*
  122.              * don't free both ml_hostname & ml_directory.
  123.              * See rmtab_insert for details.
  124.              */
  125.             tmp = cur;
  126.             cur = cur->ml_next;
  127.             if (prv)
  128.                 prv->ml_next = cur;
  129.             else
  130.                 rmtablist    = cur;
  131.             free(tmp->ml_hostname);
  132.             free(tmp);
  133.  
  134.             changed = 1;
  135.         } else if (p0 < 0) {
  136.             prv = cur;
  137.             cur = cur->ml_next;
  138.         } else
  139.             break;                /* not found */
  140.     }
  141.  
  142.     if (changed)
  143.         rmtab_file('w');
  144. }
  145.  
  146. /*
  147.  * rmtab_gethost -- return the hostname
  148.  */
  149.  
  150. static char *rmtab_gethost(rqstp)
  151. struct svc_req *rqstp;
  152. {
  153.     struct hostent *hp;
  154.         struct in_addr addr;
  155.  
  156.     addr = svc_getcaller(rqstp->rq_xprt)->sin_addr;
  157.     hp   = gethostbyaddr((char *) &addr, sizeof(addr), AF_INET);
  158.  
  159.     if (hp)
  160.         return((char *) hp->h_name);
  161.  
  162.     return((char *) NULL);
  163. }
  164.  
  165. /*
  166.  * rmtab_insert -- a sorted link list
  167.  */
  168.  
  169. static int rmtab_insert(hostname, path)
  170. char *hostname, *path;
  171. {
  172.     int        hostlen, p0, p1;
  173.     mountlist    cur, prv;
  174.  
  175.     dprintf(D_RMTAB, "\trmtab_insert path='%s' host='%s'\n",
  176.                 path, hostname);
  177.  
  178.     for (cur = rmtablist, prv = NULL; cur; cur = cur->ml_next) {
  179.         p0 = strcmp(cur->ml_hostname, hostname);
  180.         p1 = strcmp(cur->ml_directory, path);
  181.         if (p0 > 0 || (p0 == 0 && p1 > 0))
  182.             break;                /* insert here */
  183.         else if (p0 == 0 && p1 == 0)
  184.             return(0);            /* already exists */
  185.         prv = cur;
  186.     }
  187.  
  188.     if ((cur = (mountlist) malloc(sizeof(mountbody))) == NULL) {
  189.         dprintf(L_ERROR, "failed to allocate memory for mountbody\n");
  190.         return(0);
  191.     }
  192.     /*
  193.      * since the data we are storing is really small (ie. h.x.y.z:/cur),
  194.      * allocate one memory unit for both and split it.
  195.      */
  196.     hostlen = strlen(hostname);
  197.     if ((cur->ml_hostname = (char *) malloc(hostlen+strlen(path)+2)) == NULL) {
  198.         dprintf(L_ERROR, "failed to allocate memory for mountlist buffer\n");
  199.         free(cur);
  200.         return(0);
  201.     }
  202.     cur->ml_directory = cur->ml_hostname + (hostlen + 1);
  203.  
  204.     strcpy(cur->ml_hostname, hostname);
  205.     strcpy(cur->ml_directory, path);
  206.  
  207.     if (prv) {
  208.         cur->ml_next = prv->ml_next;
  209.         prv->ml_next = cur;
  210.     } else {
  211.         cur->ml_next = rmtablist;
  212.         rmtablist    = cur;
  213.     }
  214.     return(1);
  215. }
  216.  
  217. /*
  218.  * rmtab_file -- read/write the mount list from/to rmtab file.
  219.  */
  220.  
  221. static void rmtab_file(op)
  222. char op;
  223. {
  224.     register int    c, len;
  225.     register char    *p;
  226.     char        buff[256], *host, *path;
  227.     FILE        *fp;
  228.     mountlist    cur;
  229.     struct stat    newstat;
  230.  
  231.     static time_t     old_st_mtime = 0;
  232.  
  233.     if (op == 'r') {                /* read&update llist */
  234.  
  235.         /*
  236.          * get a new stat; if file not there, create it
  237.          */
  238.         if (stat(_PATH_RMTAB, &newstat)) {
  239.             if ((fp = fopen(_PATH_RMTAB, "w")) == NULL) {
  240.                 dprintf(L_ERROR, "failed to create '%s'\n",
  241.                                 _PATH_RMTAB);
  242.                 return;
  243.             }
  244.             fclose(fp);
  245.  
  246.             if (stat(_PATH_RMTAB, &newstat)) {
  247.                 dprintf(L_ERROR, "failed to stat '%s'\n",
  248.                                 _PATH_RMTAB);
  249.                 fclose(fp);
  250.                 return;
  251.             }
  252.             old_st_mtime = newstat.st_mtime;
  253.             return;
  254.         }
  255.  
  256.         if (old_st_mtime == newstat.st_mtime)
  257.             return;                /* no change */
  258.  
  259.         if ((fp = fopen(_PATH_RMTAB, "r")) == NULL) {
  260.             dprintf(L_ERROR, "failed to open '%s'\n", _PATH_RMTAB);
  261.             return;
  262.         }
  263.  
  264.         while (rmtablist) {            /* free the old list */
  265.             cur       = rmtablist;
  266.             rmtablist = rmtablist->ml_next;
  267.             /*
  268.              * don't free both ml_hostname & ml_directory.
  269.              * See rmtab_insert for details.
  270.              */
  271.             free(cur->ml_hostname);
  272.             free(cur);
  273.         }
  274.  
  275.         while (! feof(fp)) {
  276.             /*
  277.              * the reason this looks worse than it should is so
  278.              * we don't have to do bunch of passes on the buff.
  279.              * (fgets,strlen,strchr...)
  280.              */
  281.             p    = buff;
  282.             host = buff;
  283.             path = NULL;
  284.             len  = c = 0;
  285.             while (!feof(fp) && (c = fgetc(fp))!='\n' && len<255) {
  286.                 if (c == ':') {
  287.                     c    = '\0';
  288.                     path = p+1;
  289.                 }
  290.                 *p++ = (char) c;
  291.                 len++;
  292.             }
  293.             *p = '\0';
  294.  
  295.             while (!feof(fp) && c != '\n')    /* skip if line > 255 */
  296.                 c = fgetc(fp);
  297.  
  298.             if (path)            /* skip bad input */
  299.                 if (*host && *path)
  300.                     rmtab_insert(host, path);
  301.         }
  302.         fclose(fp);
  303.         old_st_mtime = newstat.st_mtime;
  304.  
  305.     } else if (op == 'w') {                /* write from llist */
  306.  
  307.         if ((fp = fopen(_PATH_RMTAB, "w")) == NULL) {
  308.             dprintf(L_ERROR, "failed to open '%s'\n", _PATH_RMTAB);
  309.             return;
  310.         }
  311.         for (cur = rmtablist; cur; cur = cur->ml_next)
  312.             fprintf(fp, "%s:%s\n", cur->ml_hostname,
  313.                            cur->ml_directory);
  314.         fclose(fp);
  315.  
  316.         if (stat(_PATH_RMTAB, &newstat)) {
  317.             dprintf(L_ERROR, "failed to stat '%s'\n", _PATH_RMTAB);
  318.             fclose(fp);
  319.             return;
  320.         }
  321.         old_st_mtime = newstat.st_mtime;
  322.  
  323.     } else
  324.         dprintf(L_ERROR, "rmtab_file bad flag '%c'\n", op);
  325. }
  326.